home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / Draw / Sources / GroupShp.cpp < prev    next >
Encoding:
Text File  |  1996-08-16  |  20.7 KB  |  676 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                GroupShp.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Author:                Mary Boetcher
  7. //
  8. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //========================================================================================
  11.  
  12. #include "ODFDraw.hpp"
  13.  
  14. #ifndef GROUPSHP_H
  15. #include "GroupShp.h"
  16. #endif
  17.  
  18. #ifndef DRAWPART_H
  19. #include "DrawPart.h"
  20. #endif
  21.  
  22. #ifndef DRAWCLIP_H
  23. #include "DrawClip.h"
  24. #endif
  25.  
  26. #ifndef UTILS_H
  27. #include "Utils.h"
  28. #endif
  29.  
  30. #ifndef CONTENT_H
  31. #include "Content.h"
  32. #endif
  33.  
  34. // ----- Part Layer -----
  35.  
  36. #ifndef FWUTIL_H
  37. #include "FWUtil.h"
  38. #endif
  39.  
  40. // ----- OS Layer -----
  41.  
  42. #ifndef FWODGEOM_H
  43. #include "FWODGeom.h"
  44. #endif
  45.  
  46. // ----- OpenDoc Includes -----
  47.  
  48. #ifndef SOM_ODTransform_xh
  49. #include <Trnsform.xh>
  50. #endif
  51.  
  52. //========================================================================================
  53. // Runtime Information
  54. //========================================================================================
  55.  
  56. #ifdef FW_BUILD_MAC
  57. #pragma segment odfdrawshapes
  58. #endif
  59.  
  60. FW_DEFINE_CLASS_M1(CGroupShape, CBaseShape)
  61.  
  62. const FW_ClassTypeConstant LGroupShape = FW_TYPE_CONSTANT('s','h','g','p');
  63. FW_REGISTER_ARCHIVABLE_CLASS(LGroupShape, CGroupShape, CGroupShape::Read, 0, 0, CBaseShape::Write)
  64.  
  65. FW_DEFINE_AUTO(CGroupShape)
  66. FW_DEFINE_AUTO(CAllShapeIterator)
  67.  
  68. //========================================================================================
  69. // class CGroupShape
  70. //========================================================================================
  71.  
  72. //----------------------------------------------------------------------------------------
  73. // CGroupShape constructors
  74. //----------------------------------------------------------------------------------------
  75. CGroupShape::CGroupShape()
  76. :    CBaseShape(4, kGroupShape, kFrameOnly),
  77.     fShapeList(NULL)
  78. {
  79.     fShapeList = FW_NEW(CShapeCollection, ());
  80.     FW_END_CONSTRUCTOR
  81. }
  82.  
  83. //----------------------------------------------------------------------------------------
  84. CGroupShape::CGroupShape(CShapeCollection* shapeList)
  85. :    CBaseShape(4, kGroupShape, kFrameOnly)
  86. {
  87.     fShapeList = FW_NEW(CShapeCollection, ());
  88.     CShapeCollectionIterator it(shapeList);
  89.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  90.     {
  91.         fShapeList->AddLast(shape);
  92.     }
  93.     FW_END_CONSTRUCTOR
  94. }
  95.  
  96. //----------------------------------------------------------------------------------------
  97. CGroupShape::CGroupShape(FW_CReadableStream& archive)
  98. :    CBaseShape(archive)
  99. {
  100.     fShapeList = FW_NEW(CShapeCollection, ());
  101.     FW_END_CONSTRUCTOR
  102. }
  103.  
  104. //----------------------------------------------------------------------------------------
  105. // CGroupShape destructor
  106. //----------------------------------------------------------------------------------------
  107. CGroupShape::~CGroupShape()
  108. {
  109.     FW_START_DESTRUCTOR
  110.  
  111.     this->EmptyShapes(true);    // delete shapes
  112.     delete fShapeList;
  113. }
  114.  
  115. //----------------------------------------------------------------------------------------
  116. // CGroupShape::EmptyShapes
  117. //----------------------------------------------------------------------------------------
  118. void CGroupShape::EmptyShapes(FW_Boolean deleteShapes)
  119. {
  120.     if (fShapeList)
  121.     {
  122.         CBaseShape* shape;
  123.         while ((shape = fShapeList->First()) != NULL)
  124.         {
  125.             fShapeList->Remove(shape);
  126.             if (deleteShapes)
  127.             {
  128.                 FW_SOMEnvironment ev;
  129.                 shape->Deleted(ev);
  130.                 delete shape;
  131.             }
  132.         }
  133.     }
  134. }
  135.  
  136. //----------------------------------------------------------------------------------------
  137. // CGroupShape::Read
  138. //----------------------------------------------------------------------------------------
  139. void* CGroupShape::Read(FW_CReadableStream& stream, FW_ClassTypeConstant type)
  140. {
  141. FW_UNUSED(type);
  142.     CGroupShape* groupShape = FW_NEW(CGroupShape, (stream));
  143.  
  144.     // Read shapes from the stream and add them to the group
  145.     unsigned long count;
  146.     stream >> count;
  147.     for (short i = 0; i<count; i++)
  148.     {
  149.         CBaseShape* theShape = NULL;
  150.         FW_READ_DYNAMIC_OBJECT(stream, &theShape, CBaseShape);
  151.         FW_ASSERT(theShape);
  152.         
  153.         // ----- Add the shape to the group -----
  154.         groupShape->AddShape(theShape);
  155.     }
  156.  
  157.     return groupShape;
  158. }
  159.  
  160. //----------------------------------------------------------------------------------------
  161. // CGroupShape::Flatten
  162. //----------------------------------------------------------------------------------------
  163. void CGroupShape::Flatten(FW_CWritableStream& archive)
  164. {    
  165.     CBaseShape::Flatten(archive);
  166.  
  167.     unsigned long count = fShapeList->Count();
  168.     archive << count;
  169.  
  170.     // Write group shapes to the archive
  171.     CShapeCollectionIterator it(fShapeList);
  172.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  173.     {
  174.         FW_WRITE_DYNAMIC_OBJECT(archive, shape, CBaseShape);
  175.     }    
  176. }
  177.  
  178. //----------------------------------------------------------------------------------------
  179. // CGroupShape::CreateShapeOutline
  180. //----------------------------------------------------------------------------------------
  181. ODShape* CGroupShape::CreateShapeOutline(Environment* ev)
  182. {
  183.     FW_CRect bounds = GetRectGeometry();
  184.  
  185.         // We don't acquire it because we return it
  186.     ODShape* outline = ::FW_NewODShape(ev, bounds);
  187.  
  188.     ::FW_OutlineODShape(ev, outline, GetPenSize());
  189.  
  190.     return outline;
  191. }
  192.  
  193. //----------------------------------------------------------------------------------------
  194. // CGroupShape::GetClipRegion
  195. //----------------------------------------------------------------------------------------
  196. void CGroupShape::GetClipRegion(Environment* ev, ODShape* clipRegion)
  197. {
  198.     if (fShapeList->Count() == 0) return;
  199.  
  200.     ODShape* updateShape = ::FW_NewODShape(ev);
  201.  
  202.     FW_CAcquiredODShape aqTempShape = ::FW_NewODShape(ev);
  203.     FW_Boolean first = TRUE;
  204.  
  205.     CShapeCollectionIterator it(fShapeList);
  206.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  207.     {
  208.         shape->GetUpdateBox(ev, aqTempShape);
  209.         if (first)
  210.         {
  211.             updateShape->CopyFrom(ev, aqTempShape);
  212.         }
  213.         else
  214.         {
  215.             updateShape->Union(ev, aqTempShape);
  216.         }
  217.                         
  218.         first = FALSE;
  219.     }
  220. }
  221.  
  222. //----------------------------------------------------------------------------------------
  223. // CGroupShape::GetHandleCenter
  224. //----------------------------------------------------------------------------------------
  225. void CGroupShape::GetHandleCenter(short whichHandle, FW_CPoint& center) const
  226. {    
  227.     FW_CRect bounds = GetRectGeometry();
  228.  
  229.     switch (whichHandle)
  230.     {
  231.         case kInTopLeftCorner:
  232.             center.x = bounds.left;
  233.             center.y = bounds.top;
  234.             break;
  235.         case kInTopRightCorner:
  236.             center.x = bounds.right;
  237.             center.y = bounds.top;
  238.             break;
  239.         case kInBottomLeftCorner:
  240.             center.x = bounds.left;
  241.             center.y = bounds.bottom;
  242.             break;
  243.         case kInBottomRightCorner:
  244.             center.x = bounds.right;
  245.             center.y = bounds.bottom;
  246.             break;
  247.     }
  248. }
  249.  
  250. //----------------------------------------------------------------------------------------
  251. // CGroupShape::GetMapRects
  252. //----------------------------------------------------------------------------------------
  253. void CGroupShape::GetMapRects(short whichHandle, const FW_CPoint& mouseLoc,
  254.                               FW_CRect& srcRect, FW_CRect& dstRect)
  255. {
  256.     srcRect = GetRectGeometry();
  257.     dstRect = srcRect;
  258.     
  259.     switch (whichHandle)
  260.     {
  261.         case kInTopLeftCorner:
  262.             dstRect.left = mouseLoc.x;
  263.             dstRect.top = mouseLoc.y;
  264.             break;
  265.         case kInTopRightCorner:
  266.             dstRect.right = mouseLoc.x;
  267.             dstRect.top = mouseLoc.y;
  268.             break;
  269.         case kInBottomLeftCorner:
  270.             dstRect.left = mouseLoc.x;
  271.             dstRect.bottom = mouseLoc.y;
  272.             break;
  273.         case kInBottomRightCorner:
  274.             dstRect.right = mouseLoc.x;
  275.             dstRect.bottom = mouseLoc.y;
  276.             break;
  277.     }
  278. }
  279.  
  280. //----------------------------------------------------------------------------------------
  281. // CGroupShape::GetRectGeometry
  282. //----------------------------------------------------------------------------------------
  283.  
  284. FW_CRect CGroupShape::GetRectGeometry() const
  285. {
  286.     // Calculate the boundary rectangle for our shapes
  287.     FW_CRect rect = FW_kZeroRect;
  288.     if (fShapeList->Count() != 0)
  289.     {
  290.         FW_Boolean first = true;
  291.         FW_CRect tempRect;
  292.     
  293.         CShapeCollectionIterator it(fShapeList);
  294.         for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  295.         {
  296.             shape->GetDragRect(tempRect);
  297.             if (first)
  298.                 rect = tempRect;
  299.             else
  300.                 rect |= tempRect;
  301.             first = false;
  302.         }
  303.     }
  304.     return rect;
  305. }
  306.  
  307. //----------------------------------------------------------------------------------------
  308. // CGroupShape::HitTest
  309. //----------------------------------------------------------------------------------------
  310. FW_Boolean CGroupShape::HitTest(Environment* ev, FW_CGraphicContext& gc, const FW_CMouseEvent& theMouseEvent) const
  311. {
  312.     // Perform HitTest on each shape in this group
  313.     CShapeCollectionIterator it(fShapeList);
  314.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  315.     {
  316.         if (shape->HitTest(ev, gc, theMouseEvent))
  317.             return true;
  318.     }
  319.  
  320.     return false;    
  321. }
  322.  
  323. //----------------------------------------------------------------------------------------
  324. // CGroupShape::MapShape
  325. //----------------------------------------------------------------------------------------
  326. void CGroupShape::MapShape(Environment* ev, CDrawPart* part, const FW_CRect& srcRect, const FW_CRect& dstRect)
  327. {
  328.     // Map each shape in this group
  329.     CShapeCollectionIterator it(fShapeList);
  330.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  331.     {
  332.         shape->MapShape(ev, part, srcRect, dstRect);
  333.     }
  334. }
  335.  
  336. //----------------------------------------------------------------------------------------
  337. // CGroupShape::OffsetShape
  338. //----------------------------------------------------------------------------------------
  339. void CGroupShape::OffsetShape(Environment* ev, FW_Fixed xDelta, FW_Fixed yDelta)
  340. {
  341.     ClearCache();
  342.  
  343.     // Offset each shape in this group
  344.     CShapeCollectionIterator it(fShapeList);
  345.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  346.     {
  347.         shape->OffsetShape(ev, xDelta, yDelta);
  348.     }
  349. }
  350.  
  351. //----------------------------------------------------------------------------------------
  352. // CGroupShape::RenderShape
  353. //----------------------------------------------------------------------------------------
  354. void CGroupShape::RenderShape(Environment* ev, ODFacet* facet, FW_CGraphicContext& gc)
  355. {    
  356.     // Render each shape in this group
  357.     CShapeCollectionIterator it(fShapeList);
  358.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  359.     {
  360.         shape->RenderShape(ev, facet, gc);
  361.     }
  362. }
  363.  
  364. //----------------------------------------------------------------------------------------
  365. // CGroupShape::ResizeFeedback
  366. //----------------------------------------------------------------------------------------
  367. void CGroupShape::ResizeFeedback(FW_CGraphicContext& gc, const FW_CInk& ink, const FW_CStyle& style, 
  368.                                  short whichHandle, const FW_CPoint& mouseLoc)
  369. {
  370.     FW_CRect srcRect, dstRect;
  371.     GetMapRects(whichHandle, mouseLoc, srcRect, dstRect);
  372.     dstRect.Sort();
  373.     OutlineShape(gc, ink, style, dstRect);
  374. }
  375.  
  376. //----------------------------------------------------------------------------------------
  377. // CGroupShape::SetShapeGeometry
  378. //----------------------------------------------------------------------------------------
  379. void CGroupShape::SetShapeGeometry(const FW_CPoint& anchorPoint, const FW_CPoint& currentPoint)
  380. {
  381.     FW_CRect rect = GetRectGeometry();
  382.  
  383.     if (anchorPoint.x < currentPoint.x)
  384.     {
  385.         rect.left = anchorPoint.x;
  386.         rect.right = currentPoint.x;
  387.     }
  388.     else
  389.     {
  390.         rect.left = currentPoint.x;
  391.         rect.right = anchorPoint.x;
  392.     }
  393.     
  394.     if (anchorPoint.y < currentPoint.y)
  395.     {
  396.         rect.top = anchorPoint.y;
  397.         rect.bottom = currentPoint.y;
  398.     }
  399.     else
  400.     {
  401.         rect.top = currentPoint.y;
  402.         rect.bottom = anchorPoint.y;
  403.     }
  404.  
  405.     /* How to change group shape's geometry? */
  406. }
  407.  
  408. //----------------------------------------------------------------------------------------
  409. // CGroupShape::OutlineShape
  410. //----------------------------------------------------------------------------------------
  411. void CGroupShape::OutlineShape(FW_CGraphicContext& gc, const FW_CInk& ink, const FW_CStyle& style, const FW_CRect& rect)
  412. {
  413.     FW_CRect bounds(rect);
  414.     AdjustRectForPenSize(bounds, style.GetPenSize());
  415.     FW_CRectShape::RenderRect(gc,
  416.                               bounds,
  417.                               FW_kFrame,
  418.                               ink, style);
  419. }
  420.  
  421. //----------------------------------------------------------------------------------------
  422. // CGroupShape::Removed
  423. //----------------------------------------------------------------------------------------
  424. void CGroupShape::Removed(Environment* ev)
  425. {
  426.     CBaseShape::Removed(ev);
  427.     
  428.     // Call Removed on each shape in this group
  429.     CShapeCollectionIterator it(fShapeList);
  430.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  431.     {
  432.         shape->Removed(ev);
  433.     }
  434. }
  435.  
  436. //----------------------------------------------------------------------------------------
  437. // CGroupShape::SelectShape
  438. //----------------------------------------------------------------------------------------
  439. void CGroupShape::SelectShape(Environment* ev, FW_Boolean state)
  440. {
  441.     CBaseShape::SelectShape(ev, state);
  442.     
  443.     // ----- Select all the shapes in this group ----
  444.     CShapeCollectionIterator it(fShapeList);
  445.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  446.     {
  447.         shape->SelectShape(ev, state);
  448.     }
  449. }
  450.  
  451. //----------------------------------------------------------------------------------------
  452. // CGroupShape::SubtractToWindowClip
  453. //----------------------------------------------------------------------------------------
  454. void CGroupShape::SubtractToWindowClip(Environment* ev, 
  455.                                         CDrawFacetClipper* facetClipper, 
  456.                                         ODFacet* containingFacet, 
  457.                                         ODShape* windowClip, ODShape* tempShape)
  458. {
  459.     // Call SubtractToWindowClip on each shape in this group
  460.     CShapeCollectionIterator it(fShapeList);
  461.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  462.     {
  463.         shape->SubtractToWindowClip(ev, facetClipper, containingFacet, windowClip, tempShape);
  464.     }
  465. }
  466.  
  467. //----------------------------------------------------------------------------------------
  468. // CGroupShape::AddShape
  469. //----------------------------------------------------------------------------------------
  470. void CGroupShape::AddShape(CBaseShape* shape)
  471. {
  472.     fShapeList->AddLast(shape);
  473. }
  474.  
  475. //----------------------------------------------------------------------------------------
  476. // CGroupShape::CountShapes
  477. //----------------------------------------------------------------------------------------
  478. unsigned long CGroupShape::CountShapes() const
  479. {
  480.     return fShapeList->Count();
  481. }
  482.  
  483. //----------------------------------------------------------------------------------------
  484. // CGroupShape::GetFirstShape
  485. //----------------------------------------------------------------------------------------
  486. CBaseShape* CGroupShape::GetFirstShape() const
  487. {
  488.     return fShapeList->First();
  489. }
  490.  
  491. //----------------------------------------------------------------------------------------
  492. // CGroupShape::RemoveShapes
  493. //----------------------------------------------------------------------------------------
  494. void CGroupShape::RemoveShapes()
  495. {
  496.     this->EmptyShapes(false);
  497. }
  498.  
  499. //----------------------------------------------------------------------------------------
  500. // CGroupShape::Remove1Shape
  501. //----------------------------------------------------------------------------------------
  502. void CGroupShape::Remove1Shape(CBaseShape* shape)
  503. {
  504.     fShapeList->Remove(shape);
  505. }
  506.  
  507. //----------------------------------------------------------------------------------------
  508. // CGroupShape::ChangeFillColor
  509. //----------------------------------------------------------------------------------------
  510. void CGroupShape::ChangeFillColor(Environment* ev, CDrawPart* part, const FW_CColor& color)
  511. {
  512.     CBaseShape::ChangeFillColor(ev, part, color);
  513.  
  514.     CShapeCollectionIterator it(fShapeList);
  515.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  516.     {
  517.         shape->ChangeFillColor(ev, part, color);
  518.     }
  519. }
  520.  
  521. //----------------------------------------------------------------------------------------
  522. // CGroupShape::ChangeFrameColor
  523. //----------------------------------------------------------------------------------------
  524. void CGroupShape::ChangeFrameColor(Environment* ev, CDrawPart* part, const FW_CColor& color)
  525. {
  526.     CBaseShape::ChangeFrameColor(ev, part, color);
  527.  
  528.     CShapeCollectionIterator it(fShapeList);
  529.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  530.     {
  531.         shape->ChangeFrameColor(ev, part, color);
  532.     }
  533. }
  534.  
  535. //----------------------------------------------------------------------------------------
  536. // CGroupShape::ChangeFillPattern
  537. //----------------------------------------------------------------------------------------
  538. void CGroupShape::ChangeFillPattern(Environment* ev, CDrawPart* part, const FW_CPattern& pattern)
  539. {
  540.     CBaseShape::ChangeFillPattern(ev, part, pattern);
  541.  
  542.     CShapeCollectionIterator it(fShapeList);
  543.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  544.     {
  545.         shape->ChangeFillPattern(ev, part, pattern);
  546.     }
  547. }
  548.  
  549. //----------------------------------------------------------------------------------------
  550. // CGroupShape::ChangeFramePattern
  551. //----------------------------------------------------------------------------------------
  552. void CGroupShape::ChangeFramePattern(Environment* ev, CDrawPart* part, const FW_CPattern& pattern)
  553. {
  554.     CBaseShape::ChangeFramePattern(ev, part, pattern);
  555.  
  556.     CShapeCollectionIterator it(fShapeList);
  557.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  558.     {
  559.         shape->ChangeFramePattern(ev, part, pattern);
  560.     }
  561. }
  562.  
  563. //----------------------------------------------------------------------------------------
  564. // CGroupShape::ChangePenSize
  565. //----------------------------------------------------------------------------------------
  566. void CGroupShape::ChangePenSize(Environment* ev, CDrawPart* part, FW_Fixed newPenSize)
  567. {
  568.     CBaseShape::ChangePenSize(ev, part, newPenSize);
  569.  
  570.     CShapeCollectionIterator it(fShapeList);
  571.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  572.     {
  573.         shape->ChangePenSize(ev, part, newPenSize);
  574.     }
  575. }
  576.  
  577. //----------------------------------------------------------------------------------------
  578. // CGroupShape::ChangeRenderVerb
  579. //----------------------------------------------------------------------------------------
  580. void CGroupShape::ChangeRenderVerb(Environment* ev, CDrawPart* part, unsigned short renderVerb)
  581. {
  582.     CBaseShape::ChangeRenderVerb(ev, part, renderVerb);
  583.  
  584.     CShapeCollectionIterator it(fShapeList);
  585.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  586.     {
  587.         shape->ChangeRenderVerb(ev, part, renderVerb);
  588.     }
  589. }
  590.  
  591. //----------------------------------------------------------------------------------------
  592. // CGroupShape::SetSubscribeLink
  593. //----------------------------------------------------------------------------------------
  594.  
  595. void CGroupShape::SetSubscribeLink(Environment* ev, CDrawSubscribeLink* subscribeLink)
  596. {
  597.     CBaseShape::SetSubscribeLink(ev, subscribeLink);
  598.  
  599.     CShapeCollectionIterator it(fShapeList);
  600.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  601.     {
  602.         shape->SetSubscribeLink(ev, subscribeLink);
  603.     }
  604. }
  605.  
  606. //========================================================================================
  607. //    class CAllShapeIterator
  608. //========================================================================================
  609.  
  610. //----------------------------------------------------------------------------------------
  611. CAllShapeIterator::CAllShapeIterator(CShapeCollection* shapeList)
  612. :    fIter(NULL),
  613.     fTempList(NULL)
  614. {
  615.     fTempList = FW_NEW(CShapeCollection, ());
  616.     PrivFlattenList(shapeList);
  617.     fIter = FW_NEW(CShapeCollectionIterator, (fTempList));
  618.     FW_END_CONSTRUCTOR    
  619. }
  620.  
  621. //----------------------------------------------------------------------------------------
  622. CAllShapeIterator::CAllShapeIterator(CDrawContent* content)
  623. :    fIter(NULL),
  624.     fTempList(NULL)
  625. {
  626.     fTempList = FW_NEW(CShapeCollection, ());
  627.     PrivFlattenList(content->fShapeList);
  628.     fIter = FW_NEW(CShapeCollectionIterator, (fTempList));
  629.     FW_END_CONSTRUCTOR    
  630. }
  631.  
  632. //----------------------------------------------------------------------------------------
  633. CAllShapeIterator::~CAllShapeIterator()
  634. {
  635.     FW_START_DESTRUCTOR
  636.     delete fTempList;
  637.     delete fIter;
  638. }
  639.  
  640. //----------------------------------------------------------------------------------------
  641. CBaseShape* CAllShapeIterator::First()
  642. {
  643.     return fIter->First();
  644. }
  645.  
  646. //----------------------------------------------------------------------------------------
  647. CBaseShape*    CAllShapeIterator::Next()
  648. {
  649.     return fIter->Next();
  650. }
  651.  
  652. //----------------------------------------------------------------------------------------
  653. FW_Boolean CAllShapeIterator::IsNotComplete()
  654. {
  655.     return fIter->IsNotComplete();
  656. }
  657.  
  658. //----------------------------------------------------------------------------------------
  659. void CAllShapeIterator::PrivFlattenList(CShapeCollection* shapeList)
  660. {
  661.     CShapeCollectionIterator it(shapeList);
  662.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  663.     {
  664.         if (shape->GetShapeType() == kGroupShape)
  665.             PrivFlattenList(((CGroupShape*)shape)->GetShapeList());
  666.         else
  667.             fTempList->AddLast(shape);
  668.     }
  669. }
  670.  
  671. //----------------------------------------------------------------------------------------
  672. unsigned long CAllShapeIterator::CountShapes()
  673. {
  674.     return fTempList->Count();
  675. }
  676.